package com.processmining.support.C_netFormatter.format;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.deckfour.xes.model.XLog;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.processmining.support.analyseSupport.activity.impl.ActivityImpl;
import com.processmining.support.eventLogParse.impl.EventLogParseImpl;

import net.ProcessMining.mining.heuristics.HeuristicsMetrics;
import net.ProcessMining.mining.heuristics.miner.HeuristicsMiner;
import net.ProcessMining.models.heuristics.HeuristicsNet;
import net.ProcessMining.models.heuristics.SimpleHeuristicsNet;

/**
 * 因果矩阵的资源关系网形式的数据结构，不以“活动名称：concept:name”将活动分组，以“resource_attr”（event中的某个属性）分组，然后根据流程模型，建立资源关系网
 * @author admin
 *
 */
public class ResourceRelation extends Formatter implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = -804993738143726188L;
	//属性有mineUsetime、nodes、links、resource_attr
	private XLog log;
	/**
	 * resource_attr的数据类型，1-int类型，2-String类型
	 */
	private int attrType;
	/**
	 * 定义用来分组的event属性
	 */
	private String resource_attr;
	
	private List<String> attrList;
	
	
	public ResourceRelation(HeuristicsNet net, String time,String resource_attr,XLog log,int attrType, List<String> rRAttrList){
		this.nodes=new ArrayList<Node>();
		this.links=new ArrayList<Link>();
		this.mineUsetime=time;
		this.resource_attr=resource_attr;
		this.log=log;
		this.attrType=attrType;
		this.attrList = rRAttrList;
		transform((SimpleHeuristicsNet)net);
	}
	@Override
	public void transform(SimpleHeuristicsNet net) {
		Map<String,Link> linksMap=new HashMap<String,Link>();
		Map<String,Node> nodesMap=new HashMap<String,Node>();
		ActivityImpl activityImpl=new ActivityImpl();
		HeuristicsMetrics metrics = net.getMetrics();
		int size = net.size();
		Map<Integer, String> names = new HashMap<Integer, String>();
		for (int i = 0; i < size; i++) {
			names.put(i, net.getActivitiesMappingStructures()
					.getXEventClasses().getByIndex(i).toString());
		}
		Map<String,String> resourceNames=activityImpl.getEventAttribute(log, names, resource_attr, attrType);
		for (int i = 0; i < size; i++) {
			String sourceResource=resourceNames.get(names.get(i));
			nodesMap.put(sourceResource, new Node(sourceResource));
			// input
			int inputSetSize = net.getInputSet(i).size();
			for (int j = 0; j < inputSetSize; j++) {
				int subSetSize = net.getInputSet(i).get(j).size();
				for (int k = 0; k < subSetSize; k++) {
					int element = net.getInputSet(i).get(j).get(k);
					String targetResource=resourceNames.get(names.get(element));
					String linksMapKey=targetResource+"-"+sourceResource;
					if(targetResource.equals(sourceResource)){
						continue;
					}
					//System.out.println("counts:"+metrics.getDirectSuccessionCount(i, element));
					if(linksMap.containsKey(linksMapKey)){
						long counts=linksMap.get(linksMapKey).getValue()+(long) metrics.getDirectSuccessionCount(element,i);
						linksMap.get(linksMapKey).setValue(counts);
					}else{
						linksMap.put(linksMapKey, new Link(targetResource,sourceResource,(long) metrics.getDirectSuccessionCount(element,i)));
					}
				}
			}
			// 组织活动的output
			int outputSetSize = net.getOutputSet(i).size();
			for (int j = 0; j < outputSetSize; j++) {
				int subSetSize = net.getOutputSet(i).get(j).size();
				for (int k = 0; k < subSetSize; k++) {
					int element = net.getOutputSet(i).get(j).get(k);
					String targetResource=resourceNames.get(names.get(element));
					String linksMapKey=sourceResource+"-"+targetResource;
					if(targetResource.equals(sourceResource)){
						continue;
					}
					if(linksMap.containsKey(linksMapKey)){
						long counts=linksMap.get(linksMapKey).getValue()+(long) metrics.getDirectSuccessionCount(i, element);
						linksMap.get(linksMapKey).setValue(counts);
					}else{
						linksMap.put(linksMapKey, new Link(sourceResource,targetResource,(long) metrics.getDirectSuccessionCount(i, element)));
					}
				}
			}
		}
		Collection<Link> linksCollection = linksMap.values();
		this.links = new ArrayList<Link>(linksCollection);
		Collection<Node> nodesCollection = nodesMap.values();
		this.nodes = new ArrayList<Node>(nodesCollection);
	}
	public static void main(String args[]) throws FileNotFoundException, JsonProcessingException{
		InputStream in =new FileInputStream(new File("C:\\Users\\hxh12\\Desktop\\流程挖掘json格式说明\\流程挖掘json格式说明\\reviewing.xes"));
		EventLogParseImpl eventLogSumariseImpl = new EventLogParseImpl();
		XLog log = eventLogSumariseImpl.eventLogParse(in);
		HashMap<String,Object> map = new HashMap<String,Object>();
		HeuristicsMiner hm = new HeuristicsMiner(log,map);
		//TODO 返回的因果矩阵
		SimpleHeuristicsNet net = (SimpleHeuristicsNet) hm.mine();
		ActivityImpl act = new ActivityImpl();
		Set<String> attr = act.getEventAttrs(log);
		Iterator<String> i = attr.iterator();
		List<String> attrList = new ArrayList<String>();
		String s = null;
		while(i.hasNext()){
			s = i.next();
			System.out.println("attr : " + s);
			attrList.add(s);
		}
		
		Formatter formatter=new ResourceRelation(net,hm.usedTime,"org:resource",log,2,attrList);
		try
		   {
		       PrintStream out = new PrintStream("E:\\mineTest\\review-orgResource.txt");
		       System.setOut(out);
		   }
		   catch(FileNotFoundException e)
		   {
		       e.printStackTrace();
		   }
		ObjectMapper mapper = new ObjectMapper();
		System.out.println(mapper.writeValueAsString(formatter));
	}
	
	public String getResource_attr() {
		return resource_attr;
	}
	public void setResource_attr(String resource_attr) {
		this.resource_attr = resource_attr;
	}
	public List<String> getAttrList() {
		return attrList;
	}
	public void setAttrList(List<String> attrList) {
		this.attrList = attrList;
	}
	
	
	
	
	
}
